﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OfficeOpenXml;
using Prism.Commands;
using YJTTool.Common.Attributes;
using YJTTool.Common.Helper;
using YJTTool.Core;
using YJTTool.DrugControls.Model;

namespace YJTTool.DrugControls.ViewModels
{
    public class DrugControlsViewModel : InheritBase
    {
        private readonly ExcelHelper _excelHelper;
        private bool isOneClick = false;
        private string ybPath = "";
        private string importPath = "";
        private List<XlsxDto> YbxlsxList;
        private List<XlsxDto> YmzxlsxList;
        private List<XlsxDto> DzxlsxList;
        private List<XlsxDto> PpxlsxList;
        private List<XlsxDto> YbzdxlsxList;
        private List<XlsxDto> SummaryList;
        #region ctor
        public DrugControlsViewModel(ExcelHelper _excelHelper)
        {
            this._excelHelper = _excelHelper;
            Init();
            RunCommand();
        }
        #endregion

        #region 属性
        private YpdzDto ybDto;
        /// <summary>
        /// 原表Dto
        /// </summary>
        public YpdzDto YbDto
        {
            get => ybDto;
            set
            {
                ybDto = value;
                RaisePropertyChanged();
            }
        }

        private YpdzDto ymzDto;
        /// <summary>
        /// 已命中Dto
        /// </summary>
        public YpdzDto YmzDto
        {
            get => ymzDto;
            set
            {
                ymzDto = value;
                RaisePropertyChanged();
            }
        }

        private YpdzDto dzDto;
        /// <summary>
        /// 对照Dto
        /// </summary>
        public YpdzDto DzDto
        {
            get => dzDto;
            set
            {
                dzDto = value;
                RaisePropertyChanged();
            }
        }

        private YpdzDto ppDto;
        /// <summary>
        /// 匹配Dto
        /// </summary>
        public YpdzDto PpDto
        {
            get => ppDto;
            set
            {
                ppDto = value;
                RaisePropertyChanged();
            }
        }
        #endregion

        #region 命令
        /// <summary>
        /// 医保字典
        /// </summary>
        public DelegateCommand YBZDCommand { get; private set; }

        /// <summary>
        /// 原表
        /// </summary>
        public DelegateCommand YBCommand { get; private set; }

        /// <summary>
        /// 对照
        /// </summary>
        public DelegateCommand DZCommand { get; private set; }

        /// <summary>
        /// 已命中
        /// </summary>
        public DelegateCommand YMZCommand { get; private set; }

        /// <summary>
        /// 匹配
        /// </summary>
        public DelegateCommand PPCommand { get; private set; }

        /// <summary>
        /// 一键导入
        /// </summary>
        public DelegateCommand OneClickImportCommand { get; private set; }

        /// <summary>
        /// 导出SQL
        /// </summary>
        public DelegateCommand ExportSqlCommand { get; private set; }

        /// <summary>
        /// 导出XLSX
        /// </summary>
        public DelegateCommand ExportXlsxCommand { get; private set; }

        /// <summary>
        /// 跳过医保对照导出SQL
        /// </summary>
        public DelegateCommand SkipExportSqlCommand { get; private set; }

        #endregion

        #region 集合
        #endregion

        #region 方法
        private void Init()
        {
            YbDto = new YpdzDto();
            YmzDto = new YpdzDto();
            DzDto = new YpdzDto();
            PpDto = new YpdzDto();
            SummaryList = new List<XlsxDto>();
            YbzdxlsxList = new List<XlsxDto>();
            YbxlsxList = new List<XlsxDto>();
            DzxlsxList = new List<XlsxDto>();
            PpxlsxList = new List<XlsxDto>();
            YmzxlsxList = new List<XlsxDto>();
            YbDto = IniHelper.Instance.ReadFromIni<YpdzDto>("YBDto", @"./Ini/YPDZ.ini");
            YmzDto = IniHelper.Instance.ReadFromIni<YpdzDto>("YmzDto", @"./Ini/YPDZ.ini");
            DzDto = IniHelper.Instance.ReadFromIni<YpdzDto>("DzDto", @"./Ini/YPDZ.ini");
            PpDto = IniHelper.Instance.ReadFromIni<YpdzDto>("PpDto", @"./Ini/YPDZ.ini");
        }

        private void RunCommand()
        {
            YBZDCommand = new DelegateCommand(async () =>
            {
                await LoadingMaskInterceptor.Instance().InterceptAsync(async () => await GetYbzdData(importPath, "原表"));
            });

            YBCommand = new DelegateCommand(() =>
            {
                IniHelper.Instance.SaveToIni(YbDto, "YBDto", "./Ini/YPDZ.ini");
                if (!isOneClick)
                {
                    importPath = _excelHelper.ImportExcelFile();
                }
                if (importPath == null)
                {
                    return;
                }
                ybPath = importPath;
                GetYbData(importPath, "原表");
            });

            DZCommand = new DelegateCommand(() =>
            {
                IniHelper.Instance.SaveToIni(DzDto, "DzDto", "./Ini/YPDZ.ini");
                if (!isOneClick)
                {
                    importPath = _excelHelper.ImportExcelFile();
                }
                if (importPath == null)
                {
                    return;
                }
                GetDzData(importPath, "对照");
            });

            YMZCommand = new DelegateCommand(() =>
            {
                IniHelper.Instance.SaveToIni(YmzDto, "YmzDto", "./Ini/YPDZ.ini");
                if (!isOneClick)
                {
                    importPath = _excelHelper.ImportExcelFile();
                }
                if (importPath == null)
                {
                    return;
                }
                GetYmzData(importPath, "已命中");
            });

            PPCommand = new DelegateCommand(() =>
            {
                IniHelper.Instance.SaveToIni(PpDto, "PpDto", "./Ini/YPDZ.ini");
                if (!isOneClick)
                {
                    importPath = _excelHelper.ImportExcelFile();
                }
                if (importPath == null)
                {
                    return;
                }
                GetPpData(importPath, "匹配");
            });

            ExportSqlCommand = new DelegateCommand(async () =>
            {
                await LoadingMaskInterceptor.Instance().InterceptAsync(async () => await WriteSqlData());

            });

            ExportXlsxCommand = new DelegateCommand(async () =>
            {
                await LoadingMaskInterceptor.Instance().InterceptAsync(async () => await WriteExcelData());
            });

            OneClickImportCommand = new DelegateCommand(async () =>
            {
                isOneClick = true;
                importPath = _excelHelper.ImportExcelFile();
                PPCommand.Execute();
                YMZCommand.Execute();
                DZCommand.Execute();
                YBCommand.Execute();
                isOneClick = false;
            });

            SkipExportSqlCommand = new DelegateCommand(async () =>
            {
                await LoadingMaskInterceptor.Instance().InterceptAsync(async () => await SkipWriteSqlData());

            });
        }

        [ShowLoadingMask]

        private async Task WriteExcelData()
        {
            if ((YbxlsxList == null && YbzdxlsxList == null) || (YbxlsxList.Count == 0 && YbzdxlsxList.Count == 0))
            {
                MessageError("请先导入医保字典、原表数据！");
                return;
            }
            await Task.Run(() =>
            {
                try
                {
                    // 获取YBYPCODE相等的
                    var equalYBYPCODE = from ybx in YbxlsxList
                                        join ybz in YbzdxlsxList on ybx.YBYPCode equals ybz.YBYPCode
                                        select new { ybx.ID, ybx.SPDM, ybx.PZWH, ybx.OLDMEDNAME, ybx.SCCS, ybx.OLDSPAC, ybx.OLDUNIT, ybx.YBYPCode, ybz.YPZDID, ybz.MEDNAME, ybz.SPAC, ybz.UNIT,ybx.Other1};
                    // 将 YbzdxlsxList 中的 YBYPCode 存入 HashSet
                    var ybzYBYPCODESet = new HashSet<string>(YbzdxlsxList.Select(ybz => ybz.YBYPCode));

                    // 直接过滤出 YbxlsxList 中 YBYPCode 不在 ybzYBYPCODESet 中的记录
                    var notEqualRecords = YbxlsxList
                        .Where(ybx => !ybzYBYPCODESet.Contains(ybx.YBYPCode))
                        .ToArray();
                    string[] dzheaders = new string[] { };
                    dzheaders = new string[] { "序号", "商品代码", "批准文号", "通用名", "生产厂商", "包装", "单位", "医保药品编号", "商品代码", "药品字典ID", "药品名称", "包装", "单位", };

                    string[] dclheaders = new string[] { };
                    if (YbDto != null && !string.IsNullOrWhiteSpace(YbDto.DiyOther1Name) && !string.IsNullOrWhiteSpace(YbDto.DiyOther1Data))
                    {
                        dclheaders = new string[] { "序号", "批准文号", "通用名", "生产厂商", "包装", "单位", "医保药品编号", "商品代码", YbDto.DiyOther1Name };

                    }
                    else
                    {
                        dclheaders = new string[] { "序号", "批准文号", "通用名", "生产厂商", "包装", "单位", "医保药品编号", "商品代码"};

                    }
                    List<string[]> dcldata = new List<string[]>(notEqualRecords.Length); // 预分配内存
                    List<string[]> dzdata = new List<string[]>(); // 预分配内存

                    foreach (var item in notEqualRecords)
                    {
                        string[] itemData = new string[] { item.ID, item.PZWH, item.OLDMEDNAME, item.SCCS, item.OLDSPAC, item.OLDUNIT, item.YBYPCode, item.SPDM,item.Other1};
                        dcldata.Add(itemData);
                    }
                    ExcelHelper.Instance.WriteDataToExcel(ybPath, dclheaders, dcldata, "待处理");
                    foreach (var item in equalYBYPCODE.ToArray())
                    {
                        string[] itemData = new string[] { item.ID, item.SPDM,item.PZWH, item.OLDMEDNAME, item.SCCS, item.OLDSPAC, item.OLDUNIT, item.YBYPCode, item.SPDM, item.YPZDID,item.MEDNAME, item.SPAC, item.UNIT, item.Other1 };
                        dzdata.Add(itemData);
                    }
                    ExcelHelper.Instance.WriteDataToExcel(ybPath, dzheaders, dzdata, "对照");
                }
                catch (Exception ex)
                {
                    MessageError(ex.Message);
                }
            });
        }
        private async Task SkipWriteSqlData()
        {
            // 提前检查空值
            if (YbxlsxList == null || !YbxlsxList.Any())
            {
                MessageError("请导入原表数据");
                return;
            }
            if (PpxlsxList == null || !PpxlsxList.Any())
            {
                MessageError("请导入匹配数据");
                return;
            }
            await Task.Run(() =>
            {
                var insertSql = new StringBuilder();
                SummaryList.AddRange(PpxlsxList.Concat(YmzxlsxList).Concat(DzxlsxList));
                foreach (var item in YbxlsxList)
                {
                    var item1 = SummaryList.FirstOrDefault(s => s.ID == item.ID);
                    if (item1 == null)
                    {
                        continue;
                    }
                    insertSql.AppendLine($"INSERT INTO cf_u_med_change(OLDMEDNAME, OLDSPAC, OLDUNIT, ERPCODE, YPZDID, MEDNAME, SPAC, UNIT) VALUES ('{item.OLDMEDNAME}', '{item.OLDSPAC}', '{item.OLDUNIT}', '{item.SPDM}', '{item1.YPZDID}', '{item1.MEDNAME}', '{item1.SPAC}', '{item1.UNIT}');");

                }

                var exPath = _excelHelper.ExportExcelFile();

                try
                {
                    // 使用 StreamWriter 写入文件，避免多次 I/O 操作
                    File.WriteAllText(exPath, insertSql.ToString());
                }
                catch (Exception ex)
                {
                    // 捕获异常并处理（可以记录日志或提示用户）
                    Console.WriteLine($"An error occurred: {ex.Message}");
                }
            });
        }
        [ShowLoadingMask]
        private async Task WriteSqlData() 
        {
            // 提前检查空值
            if (YbxlsxList == null || !YbxlsxList.Any())
            {
                MessageError("请导入原表数据");
                return;
            }
            if (PpxlsxList == null || !PpxlsxList.Any())
            {
                MessageError("请导入匹配数据");
                return;
            }
            if (YbzdxlsxList == null || !YbzdxlsxList.Any())
            {
                MessageError("请导入医保字典数据");
                return;
            }
            await Task.Run(() => 
            {
                var insertSql = new StringBuilder();
                SummaryList.AddRange(PpxlsxList.Concat(YmzxlsxList).Concat(DzxlsxList));
                foreach (var item in YbxlsxList)
                {
                    var item1 = SummaryList.FirstOrDefault(s => s.ID == item.ID);
                    if (item1 == null)
                    {
                        continue;
                    }
                    var data = YbzdxlsxList.FirstOrDefault(s => s.YBYPCode == item1.YBYPCode);
                    if (item.isBmz == false && data != null)
                    {
                        item1.OLDMEDNAME = data.MEDNAME;
                        item1.MEDNAME = data.MEDNAME;
                        item1.SPAC = data.SPAC;
                        item1.UNIT = data.UNIT;
                    }
                    insertSql.AppendLine($"INSERT INTO cf_u_med_change(OLDMEDNAME, OLDSPAC, OLDUNIT, ERPCODE, YPZDID, MEDNAME, SPAC, UNIT) VALUES ('{item.OLDMEDNAME}', '{item.OLDSPAC}', '{item.OLDUNIT}', '{item.SPDM}', '{item1.YPZDID}', '{item1.MEDNAME}', '{item1.SPAC}', '{item1.UNIT}');");

                }

                var exPath = _excelHelper.ExportExcelFile();

                try
                {
                    // 使用 StreamWriter 写入文件，避免多次 I/O 操作
                    File.WriteAllText(exPath, insertSql.ToString());
                }
                catch (Exception ex)
                {
                    // 捕获异常并处理（可以记录日志或提示用户）
                    Console.WriteLine($"An error occurred: {ex.Message}");
                }
            });
        }

        [ShowLoadingMask]
        private async Task GetYbzdData(string filePath, string sheetName)
        {
            try
            {
                importPath = _excelHelper.ImportExcelFile();
                if (importPath == null)
                {
                    return;
                }
                filePath = importPath;
                YbzdxlsxList = new List<XlsxDto>();
                await Task.Run(() =>
                {
                    using (var package = new ExcelPackage(new FileInfo(filePath)))
                    {
                        // 获取指定名称的工作表
                        var worksheet = package.Workbook.Worksheets[sheetName];

                        if (worksheet == null)
                        {
                            MessageWarning($"工作表 {sheetName} 不存在!");
                            YbzdxlsxList = new List<XlsxDto>();
                            return;
                        }

                        int rowCount = worksheet.Dimension.Rows; // 获取行数
                                                                 // 从第二行开始读取（假设第一行是表头）
                        Parallel.For(2, rowCount + 1, row =>
                        {
                            var xlsx = new XlsxDto
                            {
                                YBYPCode = worksheet.Cells[row, 1].Text, // 医保编码
                                MEDNAME = worksheet.Cells[row, 9].Text,  // 药品名称
                                SPAC = worksheet.Cells[row, 10].Text,    // 规格
                                YPZDID = worksheet.Cells[row, 2].Text,    // 规格
                                UNIT = worksheet.Cells[row, 11].Text,    // 单位
                            };

                            // 使用锁确保线程安全
                            lock (YbxlsxList)
                            {
                                YbzdxlsxList.Add(xlsx);
                            }
                        });
                    }
                });
            }
            catch (Exception ex)
            {
                MessageError($"错误信息:{ex.Message}");
            }
        }

        private void GetYbData(string filePath, string sheetName)
        {
            try
            {
                YbxlsxList = new List<XlsxDto>();
                using (var package = new ExcelPackage(new FileInfo(filePath)))
                {
                    // 获取指定名称的工作表
                    var worksheet = package.Workbook.Worksheets[sheetName];

                    if (worksheet == null)
                    {
                        MessageWarning($"工作表 {sheetName} 不存在!");
                        YbxlsxList = new List<XlsxDto>();
                        return;
                    }

                    int rowCount = worksheet.Dimension.Rows; // 获取行数
                                                             // 从第二行开始读取（假设第一行是表头）
                    for (int row = 2; row <= rowCount; row++)
                    {
                        var xlsx = new XlsxDto
                        {
                            ID = worksheet.Cells[row, YbDto.XH.ToIndex()].Text,//序号
                            SPDM = worksheet.Cells[row, YbDto.SPDM.ToIndex()].Text,//商品代码
                            PZWH = worksheet.Cells[row, YbDto.PZWH.ToIndex()].Text,//批准文号
                            OLDMEDNAME = worksheet.Cells[row, YbDto.YPMC.ToIndex()].Text,//原表名称
                            SCCS = worksheet.Cells[row, YbDto.SCCS.ToIndex()].Text,//生产厂商
                            OLDSPAC = worksheet.Cells[row, YbDto.GG.ToIndex()].Text,//原表规格
                            OLDUNIT = worksheet.Cells[row, YbDto.DW.ToIndex()].Text,//原表单位
                            YBYPCode = worksheet.Cells[row, YbDto.YBBM.ToIndex()].Text,//医保Code
                            ERPCODE = worksheet.Cells[row, YbDto.SPDM.ToIndex()].Text,//erpcode
                            Other1 = string.IsNullOrEmpty(YbDto.DiyOther1Data) ? "": worksheet.Cells[row, YbDto.DiyOther1Data.ToIndex()].Text,//erpcode
                        };
                        YbxlsxList.Add(xlsx);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageError($"错误信息:{ex.Message}");
            }
        }

        private void GetYmzData(string filePath, string sheetName)
        {
            try
            {
                YmzxlsxList = new List<XlsxDto>();
                using (var package = new ExcelPackage(new FileInfo(filePath)))
                {
                    // 获取指定名称的工作表
                    var worksheet = package.Workbook.Worksheets[sheetName];

                    if (worksheet == null)
                    {
                        MessageWarning($"工作表 {sheetName} 不存在!");
                        YmzxlsxList = new List<XlsxDto>();
                        return;
                    }

                    int rowCount = worksheet.Dimension.Rows; // 获取行数
                                                             // 从第二行开始读取（假设第一行是表头）
                    for (int row = 2; row <= rowCount; row++)
                    {
                        var xlsx = new XlsxDto
                        {
                            ID = worksheet.Cells[row, YmzDto.XH.ToIndex()].Text,                  //序号
                            MEDNAME = worksheet.Cells[row, YmzDto.YPMC.ToIndex()].Text,             //药品名称
                            SPAC = worksheet.Cells[row, YmzDto.GG.ToIndex()].Text,               //规格
                            UNIT = worksheet.Cells[row, YmzDto.DW.ToIndex()].Text,               //单位
                            YPZDID = worksheet.Cells[row, YmzDto.ZDID.ToIndex()].Text              //药品诊断id
                        };
                        YmzxlsxList.Add(xlsx);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageError($"错误信息:{ex.Message}");
            }
        }

        private void GetDzData(string filePath, string sheetName)
        {
            try
            {
                DzxlsxList = new List<XlsxDto>();
                using (var package = new ExcelPackage(new FileInfo(filePath)))
                {
                    // 获取指定名称的工作表
                    var worksheet = package.Workbook.Worksheets[sheetName];

                    if (worksheet == null)
                    {
                        MessageWarning($"工作表 {sheetName} 不存在!");
                        DzxlsxList = new List<XlsxDto>();
                        return;
                    }

                    int rowCount = worksheet.Dimension.Rows; // 获取行数
                                                             // 从第二行开始读取（假设第一行是表头）
                    for (int row = 2; row <= rowCount; row++)
                    {
                        var xlsx = new XlsxDto
                        {
                            ID = worksheet.Cells[row, DzDto.XH.ToIndex()].Text,                  //序号
                            MEDNAME = worksheet.Cells[row, DzDto.YPMC.ToIndex()].Text,             //药品名称
                            SPAC = worksheet.Cells[row, DzDto.GG.ToIndex()].Text,               //规格
                            UNIT = worksheet.Cells[row, DzDto.DW.ToIndex()].Text,               //单位
                            YBYPCode = worksheet.Cells[row, DzDto.YBBM.ToIndex()].Text,    //单位
                            YPZDID = worksheet.Cells[row, DzDto.ZDID.ToIndex()].Text              //药品诊断id
                        };
                        DzxlsxList.Add(xlsx);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageError($"错误信息:{ex.Message}");
            }

        }

        private void GetPpData(string filePath, string sheetName)
        {
            try
            {
                PpxlsxList = new List<XlsxDto>();
                using (var package = new ExcelPackage(new FileInfo(filePath)))
                {
                    // 获取指定名称的工作表
                    var worksheet = package.Workbook.Worksheets[sheetName];

                    if (worksheet == null)
                    {
                        MessageWarning($"工作表 {sheetName} 不存在!");
                        PpxlsxList = new List<XlsxDto>();
                    }

                    int rowCount = worksheet.Dimension.Rows; // 获取行数
                                                             // 从第二行开始读取（假设第一行是表头）
                    for (int row = 2; row <= rowCount; row++)
                    {
                        if (string.IsNullOrEmpty(worksheet.Cells[row, PpDto.YPMC.ToIndex()].Text) && string.IsNullOrEmpty(worksheet.Cells[row, PpDto.DW.ToIndex()].Text))
                        {
                            continue;
                        }
                        var xlsx = new XlsxDto
                        {
                            ID = worksheet.Cells[row, PpDto.XH.ToIndex()].Text,                  //序号
                            MEDNAME = worksheet.Cells[row, PpDto.YPMC.ToIndex()].Text,             //药品名称
                            SPAC = worksheet.Cells[row, PpDto.GG.ToIndex()].Text,               //规格
                            UNIT = worksheet.Cells[row, PpDto.DW.ToIndex()].Text,               //单位
                            YPZDID = worksheet.Cells[row, PpDto.ZDID.ToIndex()].Text              //药品诊断id
                        };
                        PpxlsxList.Add(xlsx);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageError($"错误信息:{ex.Message}");
            }

        }
        #endregion

    }
}
